using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Xml;
using Lime49.UI;
using LockCrypt.Core;
using LockCrypt.DAL;

namespace LockCrypt {
    public class NestableDropTargetAdvisor : IDropTargetAdvisor {
        public UIElement TargetUI { get; set; }

        public bool IsValidDataObject(IDataObject obj) {
            return obj.GetDataPresent(typeof(Account)) || obj.GetDataPresent(typeof(Group));
        }

        public void OnDropCompleted(IDataObject obj, INestable dropTarget) {
            string newParentId = null;
            if(dropTarget is IAccount) {
                newParentId = (dropTarget as IAccount).ParentID;
            } else if(dropTarget is IGroup) {
                newParentId = (dropTarget as IGroup).ID;
            }
            var worker = new BackgroundWorker();
            if(obj.GetDataPresent(typeof(Account))) { // no, IAccount won't work...
                Account droppedAccount = obj.GetData(typeof(Account)) as Account;
                if(droppedAccount.ParentID == newParentId)
                    return;
                droppedAccount.ParentID = newParentId;
                worker.DoWork += (s, dwe) => DalConfigurationManager.Provider.EditAccount(droppedAccount);
            } else if(obj.GetDataPresent(typeof(Group))) {
                Group droppedGroup = obj.GetData(typeof(Group)) as Group;
                // check for not dragging a parent inside it's child, or a descendant of a child
                var childGroups = droppedGroup.Flatten().OfType<IGroup>();
                var unavailableIds = childGroups.Select(g => g.ID);
                if(droppedGroup.ParentID == newParentId || unavailableIds.Contains(newParentId)) { // either the same parent, or dropped onto a descendant
                    return;
                }
                droppedGroup.ParentID = newParentId;
                worker.DoWork += (s, dwe) => DalConfigurationManager.Provider.EditGroup(droppedGroup);
            } else {
                return;
            }
            worker.RunWorkerCompleted += (s, rwe) => {
                if(rwe.Error != null) {
                    DialogBox.ShowAlert(Window.GetWindow(TargetUI), rwe.Error.Message, I18nUtils.GetString("Errors", "ErrorSaving"));
                }
                NavigationCommands.Refresh.Execute(null, Window.GetWindow(TargetUI));
            };
            worker.RunWorkerAsync();
        }
        public UIElement GetVisualFeedback(IDataObject obj) {
            UIElement elt = obj.GetData("uielement") as UIElement;
            /*elt.Opacity = 0.65;
            elt.IsHitTestVisible = false;

            DoubleAnimation anim = new DoubleAnimation(0.75, new Duration(TimeSpan.FromMilliseconds(500)));
            anim.From = 0.25;
            anim.AutoReverse = true;
            anim.RepeatBehavior = RepeatBehavior.Forever;
            elt.BeginAnimation(UIElement.OpacityProperty, anim);*/

            return elt;
        }
    }
}